package com.wolfeyes.framework.web.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import com.wolfeyes.framework.web.serializer.annotation.DictAnnotation;
import com.wolfeyes.framework.web.serializer.entity.DictVO;
import com.wolfeyes.framework.web.serializer.enums.BaseEnum;
import com.wolfeyes.framework.web.serializer.exception.DictSerializerException;

import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;

/**
 * @title 字符串（数据库的字典字段code）转翻译字典的序列化器
 * @className StringAsDictDeserializer
 * @author yanyljava
 * @create 2022-01-14 21:25
 */
@Slf4j
public class StringAsDictSerializer extends JsonSerializer<String> implements ContextualSerializer {

	/**
	 * @title 自定义的注解元数据信息（即：翻译字典字段code的注解标记）
	 */
	private DictAnnotation dictAnnotation;

	public StringAsDictSerializer(DictAnnotation dictAnnotation) {
		
		this.dictAnnotation = dictAnnotation;
	}

	/**
	 * @title 空构造方法
	 */
	public StringAsDictSerializer() {
		
	}
	
	/**
	 * @title 序列化操作
	 * @title 数据库字典字段code回显前端字典枚举值的自动序列化转换逻辑
	 * @param value 数据库的字典字段code值
	 */
	@SneakyThrows
	@Override
	public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
		
		if(dictAnnotation == null) {
			
			log.error("dict annotation not found");
			return ;
		}
		
		Class<? extends Enum> typeClazz = this.dictAnnotation.type();
		// 通过当前数据库字典字段code值获取字典类型Enum
		BaseEnum typeEnum = Arrays.stream(typeClazz.getEnumConstants()).map(t -> (BaseEnum) t)
				.filter(t -> Objects.equals(t.getCode(), value))
				.findAny().orElse(null);
		// 当前数据库字典字段code值的字典类型枚举值Enum
		if(typeEnum == null) {
			throw new DictSerializerException("value is error, not found enum type");
		}
		DictVO dictVO = new DictVO();
		// 获取字典值
		dictVO.setCode(typeEnum.getCode());
		// 获取翻译文本
		dictVO.setText(typeEnum.getText());
		// 回显前端字典枚举值（自动序列化转换）
		jsonGenerator.writeObject(dictVO);
	}

	@Override
	public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty beanProperty) throws JsonMappingException {
		// 实现ContextualSerializer接口，从BeanProperty属性中获取对应的（自定义）注解元数据信息
		DictAnnotation dictAnnotation = Optional.ofNullable(beanProperty).map(item -> item.getAnnotation(DictAnnotation.class)).orElse(null);
		return new StringAsDictSerializer(dictAnnotation);
	}
	
}

